﻿//Copyright (c) 2013 Tilo Szepan, Immo Wache
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
//documentation files (the "Software"), to deal in the Software without restriction, including without limitation
//the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
//and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all copies or substantial portions 
//of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
//CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//DEALINGS IN THE SOFTWARE.


using System;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using System.ComponentModel;
using MonoMobile.Dialogs.Remote.Discovery;

namespace DuinoClient

{
    public class JSEditor : Form
    {
        FormMain _main;
        Button btn_apply;
        TextBox text_out, text_in;
        ComboBox pathSelect, methodSelect;
        WebClient client;

        public JSEditor(FormMain main, string initAddr)
        {
            _main = main;
            text_out = new TextBox();
            text_out.Multiline = true;
            text_out.WordWrap = false;
            text_out.AcceptsTab = true;
            text_out.ScrollBars = ScrollBars.Both;
            text_out.Dock = DockStyle.Fill;
            text_in = new TextBox();
            text_in.ReadOnly = true;
            text_in.Multiline = true;
            text_in.WordWrap = false;
            text_in.ScrollBars = ScrollBars.Both;
            text_in.Dock = DockStyle.Fill;

            var split = new SplitContainer();
            split.Orientation = Orientation.Horizontal;
            split.BorderStyle = BorderStyle.Fixed3D;
            split.Panel1.Controls.Add(text_out);
            split.Panel2.Controls.Add(text_in);
            split.Panel2.AutoScroll = true;
            split.Dock = DockStyle.Fill;

            Controls.Add(split);
            Controls.Add(createToolbar(String.IsNullOrEmpty(initAddr) ? "http://" : initAddr));
            Controls.Add(Buttons());

            Size = new Size(400, 300);
            Text = "JSEditor";
            client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);
        }
        Control Buttons()
        {
            var btn_cancel = new Button();
            btn_cancel.Text = "Cancel";
            btn_cancel.AutoSize = true;
            btn_cancel.Dock = DockStyle.Right;
            btn_cancel.Click += delegate { Close(); };
            btn_apply = new Button();
            btn_apply.Text = "Send";
            btn_apply.AutoSize = true;
            btn_apply.Dock = DockStyle.Right;
//            btn_apply.Enabled = false;
            btn_apply.Click += apply_clicked;
            var c = new Control();
            c.Controls.Add(btn_apply);
            c.Controls.Add(btn_cancel);
            c.Dock = DockStyle.Bottom;
            c.Height = 30;
            return c;
        }
        Control createToolbar(string addr)
        {
            var gb = new Control();
            pathSelect = new ComboBox();
            pathSelect.Text = addr;
            pathSelect.Font = new Font(pathSelect.Font.FontFamily, 10);
            pathSelect.KeyPress += new KeyPressEventHandler(pathSelect_KeyPress);

            methodSelect = new ComboBox();
            methodSelect.ImeMode = ImeMode.Disable;
            methodSelect.Items.AddRange(new[] { "GET", "PUT", "POST" });
            methodSelect.SelectedIndex = 0;
            methodSelect.Font = new Font(pathSelect.Font.FontFamily, 10);
            methodSelect.FlatStyle = FlatStyle.Popup;
            methodSelect.BackColor = Color.LightGray;
            methodSelect.Dock = DockStyle.Right;

            pathSelect.Dock = DockStyle.Fill;
            gb.Controls.Add(pathSelect);
            gb.Controls.Add(methodSelect);
            gb.Height = 25;
            gb.Dock = DockStyle.Top;
            return gb;
        }

        void pathSelect_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter && !pathSelect.DroppedDown)
            {
                apply_clicked(null, null);
                e.Handled = true;
            }
        }

        void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
        {
            if(CheckArgs(e))
                text_in.Text = e.Result.Replace("\n", Environment.NewLine);
        }

        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (CheckArgs(e))
            {
                text_in.Text = e.Result.Replace("\n", Environment.NewLine);
                text_out.Text = text_in.Text;
            }
        }
        bool CheckArgs(AsyncCompletedEventArgs e)
        {
            EndWait();
            if (e.Error != null || e.Cancelled)
            {
                HandleExceptions(e.Error);
                return false;
            }
            return true;
        }

        void apply_clicked(object sender, EventArgs e)
        {
            try
            {
                BeginWait();
                if (methodSelect.SelectedIndex != 0)
                {
                    client.Headers.Add("Content-Type: text/js");
                    client.UploadStringAsync(new Uri(pathSelect.Text), methodSelect.Text, text_out.Text);
                }
                else
                    client.DownloadStringAsync(new Uri(pathSelect.Text));
            }
            catch (Exception ex)
            {
                HandleExceptions(ex);
            }
        }
        void BeginWait()
        {
            btn_apply.Enabled = false;
            this.Cursor = Cursors.WaitCursor;
//            UseWaitCursor = true;
        }
        void EndWait()
        {
            btn_apply.Enabled = true;
            Cursor = Cursors.Default;
            //UseWaitCursor = false; // bleibt Wait bis bewegt wird
            //Cursor.Hide();
            //Cursor.Show();
        }
        void HandleExceptions(Exception ex)
        {
            MessageBox.Show(ex.Message, "an error occured:",
              MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        } 
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            Finish();
        }
        void Finish() {
            Dispose();
        }
    }

}
